The ANSI/ISO C++ standardization committees are considering proposals to add type-safe pointer casts and other run-time type mechanisms into the C++ standard. When (if?) this happens, it will be easier to do run-time typing in those cases where it truly is needed (ex: for persistence), but hopefully the new syntax won't encourage abuses where if-then-else'ing the run-time type is used to replace a virtual function call.
Note that the effect of a down-cast and a virtual fn call are similar: in the member fn that results from the virtual fn call, the 'this' ptr is a downcasted version of what it used to be (it went from ptr-to-Base to ptr-to-Derived). The difference is that the virtual fn call *always* works: it never makes the wrong 'down-cast' and it automatically extends itself whenever a new subclass is created -- as if an extra 'case' or 'if/else' magically appearing in the weak typing technique. The other difference is that the client gives control to the object rather than reasoning *about* the object.